package com.runa.rccprotocol.analysis;

import JjnCollectionDecode.DataDecode;
import JjnCollectionDecode.Results;
import com.runa.monitor.comm.dto.newComm.HotMeterVO;
import com.runa.monitor.comm.dto.newComm.ValveVO;
import com.runa.protocol.analysis.ShellBufferAnalysis;
import com.runa.protocol.dto.DtuReport;
import com.runa.protocol.dto.IInterData;
import com.runa.protocol.enums.ByteOrder;
import com.runa.protocol.util.ByteUtil;
import com.runa.rccprotocol.dto.equdata.HeatMeterData;
import com.runa.rccprotocol.dto.equdata.TerminalCalendarClock;
import com.runa.rccprotocol.dto.equdata.ValveData;
import com.runa.rccprotocol.dto.jjn.Jjn8124DataAck;
import com.runa.rccprotocol.dto.runa.RunaConcenAffirmDeny;
import com.runa.rccprotocol.dto.runa.RunaConcenResponseData;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

public class Jjn8124Analysis extends ShellBufferAnalysis<byte[]> {

    private DataDecode dataDecode = new DataDecode();

    private SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHH");

    public Jjn8124Analysis() {
        super(null, 0);
    }

    @Override
    public int fill(byte[] data, int length,String n) {
        Results results = dataDecode.dataDecode(new String(data, 0, length));
        if (results.returnResult) {
            data = ByteUtil.hexStringToByte(results.returnData);
        } else {
            return 0;
        }
        length = data.length;
        interData = null;
        int begin;
        for (begin = 0; begin < length; begin++) {
            if ((data[begin] & 0xff) == 0x68) {
                break;
            }
        }
        int device = data[begin + 1] & 0xff;
        if (device == 0x82) {
            String commAddr = ByteUtil.byteToHexStringFlip(data, begin + 2, 5);
            String clientId = ByteUtil.byteToHexStringFlip(data, begin + 7, 6);
            int ctrl = data[begin + 13] & 0xff;
            int size = ByteUtil.byteToUShort(data, begin + 14, ByteOrder.BA);
            if (length < begin + size + 18) return -1;
            if (ctrl == 0x41) {
                netEquNo = commAddr;
                DtuReport report = new DtuReport(commAddr);
                report.setMustAck(true);
                report.setAck(new Jjn8124DataAck(data, begin));
                interData = report;
            } else if (isAck(ctrl)) {
                interData = new RunaConcenAffirmDeny(commAddr, true);
            } else if (ctrl == 0x46) {
                batchUpload(data, begin + 16, size);
            } else if (ctrl == 0x47) {
                singleUpload(data, begin + 16);
            } else {
                interData = new RunaConcenAffirmDeny(commAddr, false);
            }
            return (length - begin - 18 - size) * 2;
        }
        return 0;
    }

    private boolean isAck(int ctrl) {
        switch (ctrl) {
            case 0x42:
            case 0x44:
            case 0x48:
            case 0x49:
                return true;
            default:
                return false;
        }
    }

    private void batchUpload(byte[] data, int start, int size) {
        int index = start;
        int totalFrame = data[index++] & 0xff;
        int currFrame = data[index++] & 0xff;
        size -= 2;
        RunaConcenResponseData responseData = new RunaConcenResponseData();
        while (size > 0) {
            String code = ByteUtil.byteToHexString(data, index, 3);
            index += 3;
            if ("532020".equals(code)) {
                responseData.addRepData(meterIV(data, index));
                size -= 64;
                index += 61;
            } else {
                break;
            }
        }
        responseData.setTailFrame(totalFrame == currFrame);
        interData = responseData;
    }

    private void singleUpload(byte[] data, int start) {
        if (data[start] == 1 && data[start + 1] == 1) {
            String code = ByteUtil.byteToHexString(data, start + 2, 3);
            RunaConcenResponseData responseData = new RunaConcenResponseData();
            if ("532020".equals(code)) {
                responseData.addRepData(meterIV(data, start + 5));
            } else if ("533320".equals(code)) {
                responseData.addRepData(valve(data, start + 5));
            }
            interData = responseData;
        }
    }

    private HotMeterVO meterIV(byte[] data, int index) {
        HotMeterVO meterData = new HotMeterVO();
        meterData.setMeterSerial(ByteUtil.byteToHexStringFlip(data, index, 7));
        index += 7;
        try {
            meterData.setMeterDate(sdf.parse(ByteUtil.byteToHexString(data, index, 4)));
        } catch (ParseException e) {
            
        }
        index += 6;
//        meterData.setSettDateHeatColdVal((float) (ByteUtil.bcdToInt(data, index, 5, false) * 0.01));
        index += 5;
        meterData.setAccHeat((float) (ByteUtil.bcdToInt(data, index, 5, false) * 0.01));
        index += 5;
        meterData.setPower((float) (ByteUtil.bcdToInt(data, index, 4, false) * 0.01));
        index += 4;
        meterData.setFlow((float) (ByteUtil.bcdToInt(data, index, 4, false) * 0.0001));
        index += 4;
        meterData.setAccFlow((float) (ByteUtil.bcdToInt(data, index, 5, false) * 0.01));
        index += 5;
        meterData.setSupplyTemp((float) (ByteUtil.bcdToInt(data, index, 2, false) * 0.01));
        index += 3;
        meterData.setReturnTemp((float) (ByteUtil.bcdToInt(data, index, 2, false) * 0.01));
        index += 3;
        meterData.setWorkTime(ByteUtil.bcdToInt(data, index, 3, false));
        index += 10;
        meterData.setStatus(ByteUtil.byteToHexString(data, index, 2));
        return meterData;
    }

    private ValveVO valve(byte[] data, int index) {
        ValveVO valveVO = new ValveVO();
//        ValveData valveData = new ValveData();
        valveVO.setValveSerial(ByteUtil.byteToHexStringFlip(data, index, 7));
        index += 7;
        try {
            valveVO.setValveDate(sdf.parse(ByteUtil.byteToHexString(data, index, 4)));
        } catch (ParseException e) {
            
        }
        index += 10;
        int flag = data[index] & 0xff;
        if (((flag >> 5) & 1) == 1) {
//            valveData.setSwitchState(true);
            valveVO.setActOpen((float) 100);
        }
        if (((flag >> 6) & 1) == 1) {
//            valveData.setSwitchState(false);
            valveVO.setActOpen((float) 0);
        }
        ArrayList<String> list = new ArrayList<>();
        if (((flag >> 1) & 1) == 1) {
            list.add("进水故障");
//            faults = "进水故障,";
        }
        if (((flag >> 3) & 1) == 1) {
            list.add("回水故障");
//            faults += "回水故障,";
        }
        valveVO.setFaultCode(list);
        return valveVO;
    }

    public static void main(String[] args) {
        Jjn8124Analysis analysis = new Jjn8124Analysis();
        byte[] bytes = "6882379151119364619358130947420053EB73865DC5DC556F5D393567F8412E6299DE05073754A668752B7C11CB3F8BE7A07369BAA92F6629534F3827C56ABB0425E004B9BCF662A122B537705D073BED01C38E".getBytes();
//        analysis.fill(bytes, bytes.length);
//
//        bytes = "68827441531193000000000000490C0071C689E971DCDE998FF50AA0B26D".getBytes();
//        analysis.fill(bytes, bytes.length);
//
//        bytes = "68827441531193000000000000C6020014537FD4".getBytes();
//        analysis.fill(bytes, bytes.length);
//
//        System.out.println(analysis.gain());
    }
}
